﻿#include "MyApplication.h"
#include <qglobal.h>
#include <QMutexLocker>
#include <qdebug.h>
#include <QMouseEvent>
#include <QScrollBar>
#include <QMenu>
#include <QClipboard>
#include <QHeaderView>
#include <QTabWidget>
#include "CommShowMsgItemObjName.h"
#include "MenuPage.h"
#include "MsgPage.h"
#include "LoadDataPage.h"
#include "SigInstance.h"
#include "PageWidgetS.h"
#include "SappInstance.h"
#include "MenuPage.h"
#include "singletonPageWidgetS.h"
#include "singletonMsgAppTxt.h"
#include "singletonMsgStream.h"
#include "singletonLoadSettingFileData.h"
#include "singletonLoadThread.h"
#include "singletonMenus.h"
#include "CommunicationPage.h"
#include "mainwindow.h"
#include "menus.h"
const char* MyApplication::objName::loadPageTreeWdigetHeadViewObjName = "loadPageTreeWidgetHeadView";

void MyApplication::processingTabPageWidget(widgetUI::MainWindow* mainWindow) {
	// 获取页面
	widgetUI::MsgPage* msgPage = mainWindow->getMsgPage( );
	widgetUI::LoadDataPage* loadDataPage = mainWindow->getLoadDataPage( );
	widgetUI::PropertyPage* propertyPage = mainWindow->getPropertyPage( );
	widgetUI::AlgorithmPage* algorithmPage = mainWindow->getAlgorithmPage( );
	widgetUI::CommunicationPage* commPage = mainWindow->getCommPage( );
	widgetUI::MenuPage* menuPage = mainWindow->getMenuPage( );
	// 生成名称映射
	auto&& nameHash = appInstances::PageWidgetS::GetSigInstanceInstance( )->GetNameHashMap( );
	nameHash.insert(msgPage->getName( ), msgPage);
	nameHash.insert(loadDataPage->getName( ), loadDataPage);
	nameHash.insert(propertyPage->getName( ), propertyPage);
	nameHash.insert(algorithmPage->getName( ), algorithmPage);
	nameHash.insert(commPage->getName( ), commPage);
	nameHash.insert(menuPage->getName( ), menuPage);
	// 设置消息响应体
	appInstances::MsgAppTxt::instance(msgPage);
	appInstances::MsgStream::instance(msgPage);
	/*
	void ( QTabWidget::* tabPage_currentChanged)(int) = &QTabWidget::currentChanged;
	connect(tabWidget, tabPage_currentChanged, slost_method, & SigInstance::currentChanged);
	connect(tabWidget, &QTabWidget::tabBarClicked, slost_method, & SigInstance::tabBarClicked);
	connect(tabWidget, &QTabWidget::tabBarDoubleClicked, slost_method, & SigInstance::tabBarDoubleClicked);*/
	// 获取操处理类对象

	// page槽关联

	connect(mainWindow, &widgetUI::MainWindow::tabWidgetCurrentChanged, m_sigInstance, &SigInstance::tabWidgetCurrentChanged);
	connect(mainWindow, &widgetUI::MainWindow::tabWidgetTabBarClicked, m_sigInstance, &SigInstance::tabWidgetTabBarClicked);
	connect(mainWindow, &widgetUI::MainWindow::tabWidgetTabBarDoubleClicked, m_sigInstance, &SigInstance::tabWidgetTabBarDoubleClicked);
	connect(mainWindow, &widgetUI::MainWindow::listItemClicked, m_sigInstance, &SigInstance::listClick);
	// load 槽关联
	loadDataPage->setBtnSignals(widgetUI::LoadDataPage::LOADDATAPAGESIGNALSFLAG::CURRENTDIRBTNSIGNALS | widgetUI::LoadDataPage::LOADDATAPAGESIGNALSFLAG::MENUBTNSIGNALS | widgetUI::LoadDataPage::LOADDATAPAGESIGNALSFLAG::UPDATEBTNSIGNALS | widgetUI::LoadDataPage::LOADDATAPAGESIGNALSFLAG::UPDIRBTNSIGNALS | widgetUI::LoadDataPage::LOADDATAPAGESIGNALSFLAG::STOPUPDATEBTNSIGNALS);
	connect(loadDataPage, &widgetUI::LoadDataPage::onClick, m_sigInstance, &SigInstance::onClick);
	connect(loadDataPage, &widgetUI::LoadDataPage::upDirBtn, m_sigInstance, &SigInstance::upDirBtn);
	connect(loadDataPage, &widgetUI::LoadDataPage::updateBtn, m_sigInstance, &SigInstance::updateBtn);
	connect(loadDataPage, &widgetUI::LoadDataPage::menuBtn, m_sigInstance, &SigInstance::menuBtn);
	connect(loadDataPage, &widgetUI::LoadDataPage::resetPathDirBtn, m_sigInstance, &SigInstance::resetPathDirBtn);
	connect(loadDataPage, &widgetUI::LoadDataPage::stopUpdateBtn, m_sigInstance, &SigInstance::stopUpdateBtn);
	connect(mainWindow, &widgetUI::MainWindow::creatorPerson, m_sigInstance, &SigInstance::creatorPerson);
}

void MyApplication::processingLoadPage(const widgetUI::MainWindow* main_window) {
	auto&& nameHash = appInstances::PageWidgetS::GetSigInstanceInstance( )->GetNameHashMap( );
	widgetUI::LoadDataPage* loadPage = widgetUI::MainWindow::getLoadDataPage( );
	// connect(loadPage, &LoadDataPage::onClick, sigInstance, &::SigInstance::)
}

void MyApplication::setWinProcessing(widgetUI::MainWindow* win) {
	m_sigInstance = new SigInstance(win, win);
	appInstances::LoadDiscDirInfoThread::GetSigInstanceInstance(false, m_sigInstance, win);
	appInstances::LoadSettingFileData::GetSigInstanceInstance(false, m_sigInstance, win);
	processingTabPageWidget(win);
	processingLoadPage(win);
}

QMenu* MyApplication::notifyToMouseEvent(QWidget* mouseOnWidgetObj
	, QEvent::Type eventType
	, const QPoint& mousePos
	, const QPoint& oldMousePos) {
	/*
	 * 0~f			按下鼠标状态
	 * 10~1f		移动鼠标状态
	 * 20~2f		释放鼠标状态
	 * 100~19f		菜单响应允许状态
	 * 3a0~3ff		菜单响应完毕状态
	 * 1000~1fff	消息传递状态
	 * 3000~3fff	消息传递响应完毕状态
	 */
	// todo:日后修改为位状态
	// 基础按键消息， 0x0 为无信息状态
	constexpr static unsigned int MouseBaseStatusStart = 0x0; // 起始值
	constexpr static unsigned int MouseBaseStatusEnd = 0x10; // 限制值(不得超出)
	constexpr static unsigned int MouseMoveStatusStart = 0x10; // 鼠标移动状态
	constexpr static unsigned int MouseMoveStatusEnd = 0x20;
	constexpr static unsigned int MouseReleaseStatusStart = 0x20; // 鼠标释放状态
	constexpr static unsigned int MouseReleaseStatusEnd = 0x30;
	constexpr static unsigned int MenuTransmitStatusStart = 0x100; // 菜单传递消息
	constexpr static unsigned int MenuTransmitStatusEnd = 0x200;
	constexpr static unsigned int MenuOverStatusStart = 0x300; // 菜单响应完毕
	constexpr static unsigned int MenuOverStatusEnd = 0x400;
	constexpr static unsigned int msgTransmitStatusStart = 0x1000; // 消息传递消息
	constexpr static unsigned int msgTransmitStatusEnd = 0x2000;
	constexpr static unsigned int msgOverStatusStart = 0x3000; // 消息传递完毕
	constexpr static unsigned int msgOverStatusEnd = 0x4000;
	// 操作实例
	constexpr static unsigned int leftOnClickToMove = MouseMoveStatusStart + 2; // 左键按下并且移动
	constexpr static unsigned int mouseMove = MouseMoveStatusStart + 1; // 单纯移动
	constexpr static unsigned int mouseLeftPress = MouseBaseStatusStart + 1; // 左键按下
	constexpr static unsigned int mouseLeftRelease = MouseBaseStatusStart + 2; // 按下之后释放
	// 菜单
	constexpr static unsigned int oneMenu = MenuOverStatusStart + 1; // 1 号菜单
	constexpr static unsigned int twoMenu = MenuOverStatusStart + 2; // 2 号菜单
	constexpr static unsigned int threeMenu = MenuOverStatusStart + 3; // 3 号菜单
	// 消息传递实例
	constexpr static unsigned int copyMsg = msgTransmitStatusStart + 1;
	constexpr static unsigned int scrollMsg = msgTransmitStatusStart + 2;
	// ↑ 常量
	static unsigned int mouseMouseButtonReleaseEvent = MouseBaseStatusStart;
	static QString userNameObjName = itemName::CommShowMsgItemObjName::getUserNameObjName( );
	static QString msgObjName = itemName::CommShowMsgItemObjName::getMsgLabelObjName( );
	static QString userImageObjName = itemName::CommShowMsgItemObjName::getUserImageObjName( );
	static QString msgBoxObj = itemName::CommShowMsgItemObjName::getUserImageObjName( );
	static unsigned int mouseEventType = -1;
	static QPoint point;
	static QLabel* label = Q_NULLPTR;
	static widgetUI::CommunicationPage* page = widgetUI::MainWindow::getCommPage( );
	static auto msgBox = page->getScrollArea( );
	// 鼠标脱离控制
	if( !msgBox->geometry( ).contains(msgBox->mapFromGlobal(mousePos)) ) {
		if( mouseMouseButtonReleaseEvent == copyMsg ) {
			if( label ) {
				QClipboard* board = QApplication::clipboard( );
				board->setText(label->selectedText( ));
			}
		}
		mouseMouseButtonReleaseEvent = MouseBaseStatusStart;
		return Q_NULLPTR;
	}

	// 获取事件类型，并且鼠标状态

	if( eventType == QEvent::MouseButtonRelease ) {
		if( mouseMouseButtonReleaseEvent > MouseBaseStatusStart )
			if( mouseMouseButtonReleaseEvent == mouseLeftPress )
				mouseMouseButtonReleaseEvent = MenuTransmitStatusStart; // 单击之后直接释放
			else if( MenuOverStatusStart < mouseMouseButtonReleaseEvent && mouseMouseButtonReleaseEvent < MenuOverStatusEnd ) // 如果菜单响应完毕
				mouseMouseButtonReleaseEvent = MouseBaseStatusStart; // 恢复操作
			else if( msgTransmitStatusStart < mouseMouseButtonReleaseEvent && mouseMouseButtonReleaseEvent < msgTransmitStatusEnd )
				mouseMouseButtonReleaseEvent |= 0x2000; // 消息传递动作
			else
				mouseMouseButtonReleaseEvent = MouseBaseStatusStart; // 恢复操作
	} else {
		if( eventType == QEvent::MouseButtonPress ) {
			if( mouseMouseButtonReleaseEvent < msgTransmitStatusStart )
				mouseMouseButtonReleaseEvent = mouseLeftPress;
		} else if( eventType == QEvent::MouseMove ) {
			if( mouseMouseButtonReleaseEvent < MenuTransmitStatusStart ) {
				if( mouseMouseButtonReleaseEvent == mouseLeftPress ) {
					mouseMouseButtonReleaseEvent = leftOnClickToMove;
				} else {
					mouseMouseButtonReleaseEvent = mouseMove;
				}
			}
		} else
			return Q_NULLPTR;
	}
	// 获取事件名称
	QString eventName = mouseOnWidgetObj->objectName( );

	// 设置事件响应类型
	if( eventName == userNameObjName )
		mouseEventType = 0;
	else if( eventName == msgObjName )
		mouseEventType = 1;
	else if( eventName == userImageObjName )
		mouseEventType = 2;
	else
		return Q_NULLPTR;
	// 响应菜单弹出
	if( mouseMouseButtonReleaseEvent == MenuTransmitStatusStart ) {
		if( mouseEventType == 0 ) {
			mouseMouseButtonReleaseEvent = oneMenu; // 响应了 1 号菜单
			return appInstances::Menus::GetSigInstanceInstance( )->getUserNameMenu( );
		}
		if( mouseEventType == 1 ) {
			mouseMouseButtonReleaseEvent = twoMenu; // 响应了 2 号菜单
			return appInstances::Menus::GetSigInstanceInstance( )->getMsgMeun( );
		}
		if( mouseEventType == 2 ) {
			mouseMouseButtonReleaseEvent = threeMenu; // 响应了 3 号菜单
			return appInstances::Menus::GetSigInstanceInstance( )->getUserImageMenu( );
		} else
			return Q_NULLPTR;
	}
	if( mouseMouseButtonReleaseEvent == leftOnClickToMove ) {
		point = mousePos - oldMousePos;
		if( point.x( ) != 0 ) {
			label = qobject_cast<QLabel*>(mouseOnWidgetObj);
			mouseMouseButtonReleaseEvent = copyMsg; // 复制操作
		} else if( point.y( ) != 0 )
			mouseMouseButtonReleaseEvent = scrollMsg; // 滚动操作
	}
	// 响应自动复制操作
	if( mouseMouseButtonReleaseEvent == ( ( copyMsg ) | 0x2000 ) ) {
		if( label ) {
			QClipboard* board = QApplication::clipboard( );
			board->setText(label->selectedText( ));
		}
		return Q_NULLPTR;
	}
	if( mouseMouseButtonReleaseEvent == scrollMsg ) {
		point = mousePos - oldMousePos;
		int y = point.y( );
		if( y != 0 ) {
			QScrollBar* scrollBar = page->getVScrollBar( );
			if( y > 0 ) {
				int maximum = scrollBar->maximum( );
				int newValue = scrollBar->value( ) - qAbs(y) * 5;
				if( maximum > newValue )
					scrollBar->setValue(newValue);
			} else {
				int min = scrollBar->minimum( );
				int newValue = scrollBar->value( ) + qAbs(y) * 5;
				if( min < newValue )
					scrollBar->setValue(newValue);
			}
		}
	}
	return Q_NULLPTR;
}

bool MyApplication::notify(QObject* obj
	, QEvent* event) {
	static int mouseMouseButtonReleaseEvent = 0;
	static QPoint nowPoint;
	static QPoint oldPoint;
	static QWidget* widget;
	QEvent::Type eventType = event->type( );
	nowPoint = QCursor::pos( );
	widget = QApplication::widgetAt(nowPoint);
	if( !widget ) {
		oldPoint = nowPoint;
		return QApplication::notify(obj, event);
	}
	QMenu* mouseEventResultMenu = notifyToMouseEvent(widget, eventType, nowPoint, oldPoint);
	if( mouseEventResultMenu != Q_NULLPTR ) {
		appInstances::Menus::GetSigInstanceInstance( )->menuSetHide( );
		mouseEventResultMenu->show( );
		mouseEventResultMenu->move(nowPoint);
		oldPoint = nowPoint;
		return true;
	}
	oldPoint = nowPoint;
	return QApplication::notify(obj, event);
}

MyApplication::MyApplication(int& argc
	, char** argv
	, int i) : QApplication(argc, argv, i) {
	qsrand(1);
}

MyApplication::~MyApplication( ) {
	appInstances::Menus::GetSigInstanceInstance(true);
}
